#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>

#define PA_OFFSET		(1UL << 12)

int main(int argc, char **argv) {
	int size = 0;
	int fd = 0;
	int cp_fd = 0;
	int ret = 0;
	struct stat st_buff;
	char *addr = NULL;
	
	memset(&st_buff, 0, sizeof(struct stat));
	if (argc != 3) {
		printf("USAGE: copy file1 file2\n");
		return -1;
	}
	if (0 == access((const char *) argv[2], F_OK)) {
		printf("ERROR: the file %s existed!\n", argv[2]);
		return -1;
	}
	fd = open((const char *)argv[1], O_RDWR);
	if (0 > fd) {
		printf("Open %s file error", argv[1]);
		return -1;
	}
	ret = fstat(fd, &st_buff);
	if (0 > ret) {
		printf("Get file %s stat error\n", argv[1]);
		ret = -1;
		goto out1;
	}
//	uint32_t pa_offset = st_buff.st_size & ~(sysconf(_SC_PAGE_SIZE) - 1);
	addr = (char *) mmap(NULL, st_buff.st_size, PROT_WRITE, MAP_SHARED, fd, 0);
	if (addr == MAP_FAILED) {
		printf("mmap file %s error!\n", argv[1]);
		ret = -1;
		goto out1;
	}
	cp_fd = creat((const char *)argv[2], O_RDWR);
	if (0 > cp_fd) {
		printf("create file %s error!\n", argv[2]);
		ret = -1;
		goto out1;
	}
	size = write(cp_fd, addr, st_buff.st_size);
	if (size != st_buff.st_size) {
		printf("write file %s error!\n", argv[2]);
		ret = -1;
	}
	close(cp_fd);
out:
	munmap(addr, st_buff.st_size);
out1:
	close(fd);
	return ret;
}
